package com.gitee.service.impl;

import com.gitee.constant.GroupConstant;
import com.gitee.context.BaseContext;
import com.gitee.dto.AddMemberDTO;
import com.gitee.dto.GroupDTO;
import com.gitee.dto.SaveGroupChatDTO;
import com.gitee.entity.Group;
import com.gitee.entity.GroupChat;
import com.gitee.entity.User;
import com.gitee.entity.User2Group;
import com.gitee.exception.GroupException;
import com.gitee.mapper.GroupChatMapper;
import com.gitee.mapper.GroupMapper;
import com.gitee.mapper.User2GroupMapper;
import com.gitee.mapper.UserMapper;
import com.gitee.service.GroupService;
import com.gitee.vo.GroupChatVO;
import com.gitee.vo.GroupVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;

@Service
public class GroupServiceImpl implements GroupService {
    @Resource
    private GroupMapper groupMapper;
    @Resource
    private User2GroupMapper user2GroupMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private GroupChatMapper groupChatMapper;

    @Override
    @Transactional
    public void createGroup(GroupDTO groupDTO) {
        // 创建群聊
        Group group = new Group();
        BeanUtils.copyProperties(groupDTO, group);
        groupMapper.insert(group);

        // 获取群聊id
        Integer groupId = group.getId();
        // 把自己拉进该群
        User2Group user2Group = new User2Group();
        user2Group.setUserId(BaseContext.getCurrentId());
        user2Group.setGroupId(groupId);
        user2GroupMapper.insert(user2Group);
    }

    @Override
    @Transactional
    public void addMember(AddMemberDTO addMemberDTO) {
        if (!isAuthority(addMemberDTO.getGroupId())) {
            throw new GroupException(GroupConstant.NOT_AUTHORITY);
        }
        User2Group user2Group = new User2Group();
        BeanUtils.copyProperties(addMemberDTO, user2Group);
        user2GroupMapper.insert(user2Group);
    }

    @Override
    @Transactional
    public void removeMember(AddMemberDTO addMemberDTO) {
        if (!isAuthority(addMemberDTO.getGroupId())) {
            throw new GroupException(GroupConstant.NOT_AUTHORITY);
        }
        User2Group user2Group = new User2Group();
        BeanUtils.copyProperties(addMemberDTO, user2Group);
        user2GroupMapper.deleteByUserIdAndGroupId(user2Group);
    }

    @Override
    @Transactional
    public void deleteGroup(Integer groupId) {
        if (!isAuthority(groupId)) {
            throw new GroupException(GroupConstant.NOT_AUTHORITY);
        }

        // 首先情况群聊中的所有用户
        // 删除所有用户和该群的关系
        user2GroupMapper.deleteByGroupId(groupId);
        // 删除群聊本身
        groupMapper.deleteById(groupId);
    }

    @Override
    @Transactional
    public void editGroup(Group group) {
        // 首先判断是否为群主, 若不是则无权限
        // 通过群id查找群聊信息, 当前登录的用户是否为群主
        // 如果群聊信息中的用户id与当前登录的用户id不一致, 则无权限
        if (!isAuthority(group.getId())) {
            throw new GroupException(GroupConstant.NOT_AUTHORITY);
        }

        // 代码到这就代表有权限
        // 修改群聊信息
        groupMapper.updateById(group);
    }

    private boolean isAuthority(Integer groupId) {
        Group group = groupMapper.selectById(groupId);
        return group.getUserId().equals(BaseContext.getCurrentId());
    }

    @Override
    @Transactional
    public void leaveGroup(Integer groupId) {
        User2Group user2Group = new User2Group();
        user2Group.setUserId(BaseContext.getCurrentId());
        user2Group.setGroupId(groupId);
        user2GroupMapper.deleteByUserIdAndGroupId(user2Group);
    }

    @Override
    public GroupVO getGroupInfo(Integer id) {
        GroupVO groupVO = new GroupVO();
        // 封装group对象
        Group group = groupMapper.selectById(id);
        BeanUtils.copyProperties(group, groupVO);
        Integer groupId = group.getId();

        // 提取用户id
        List<Integer> userIds = new LinkedList<>();
        user2GroupMapper.selectByGroupId(groupId).forEach(it -> userIds.add(it.getUserId()));
        // 通过id批量查找用户
        List<User> users = userMapper.selectByIds(userIds);
        groupVO.setUserList(users);
        return groupVO;
    }

    @Override
    @Transactional
    public void saveGroupChat(SaveGroupChatDTO saveGroupChatDTO) {
        // 通过用户id和群聊id插入消息, group_chat
        GroupChat groupChat = new GroupChat();
        BeanUtils.copyProperties(saveGroupChatDTO, groupChat);
        // 判断用户是否在该群
        User2Group user2Group = user2GroupMapper.selectByGroupIdAndUserId(saveGroupChatDTO.getGroupId(), saveGroupChatDTO.getUserId());
        if (user2Group == null) {
            throw new GroupException(GroupConstant.GROUP_NOT_EXIST);
        }
        groupChatMapper.insert(groupChat);
    }

    @Override
    public List<GroupChatVO> getGroupChat(Integer groupId) {
        return groupChatMapper.selectByGroupId(groupId);
    }

    @Override
    public List<Group> getUserJoinGroup(Integer userId) {
        // 通过用户id查找群聊关系
        List<User2Group> user2Groups = user2GroupMapper.selectByUserId(userId);
        if (user2Groups == null || user2Groups.isEmpty()) {
            throw new GroupException(GroupConstant.USER_NOT_JOIN_GROUP);
        }

        List<Integer> groupIds = new LinkedList<>();
        user2Groups.forEach(it -> groupIds.add(it.getGroupId()));
        return groupMapper.selectByIds(groupIds);
    }
}
